读书笔记 numpy入门 第2章 数据切片

切片语法

1
x[start:stop:step]

如果以上 3 个参数都未指定,那么它们会被分别设置默认值 start=0stop= 维度的大小size of dimension)和 step=1

一维子数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
x = np.arange(10)
x
>>> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

x[:5] # 前五个元素

>>> array([0, 1, 2, 3, 4])

x[5:] # 索引五之后的元素

>>> array([5, 6, 7, 8, 9])

x[4:7] # 中间的子数组

>>> array([4, 5, 6])

x[::2] # 每隔一个元素

>>> array([0, 2, 4, 6, 8])

x[1::2] # 每隔一个元素,从索引1开始

>>> array([1, 3, 5, 7, 9])

逆序数组

1
2
3
4
5
6
7
x[::-1]  # 所有元素,逆序的

>>> array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

x[5::-2] # 从索引5开始每隔一个元素逆序

>>> array([5, 3, 1])

多维子数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
x2

>>> array([[12, 5, 2, 4],
[ 7, 6, 8, 8],
[ 1, 6, 7, 7]])

x2[:2, :3] # 两行,三列

>>> array([[12, 5, 2],
[ 7, 6, 8]])

x2[:3, ::2] # 所有行,每隔一列

>>> array([[12, 2],
[ 7, 8],
[ 1, 7]])

逆序数组

1
2
3
4
5
x2[::-1, ::-1]

>>> array([[ 7, 7, 6, 1],
[ 8, 8, 6, 7],
[ 4, 2, 5, 12]])

获取数组的行和列

一个冒号(:)表示空切片

1
2
3
4
5
6
7
8
9
10
11
print(x2[:, 0])  # x2的第一列

>>> [12 7 1]

print(x2[0, :]) # x2的第一行

>>> [12 5 2 4]

print(x2[0]) #等于x2[0, :]

>>> [12 5 2 4]

非副本视图的子数组

数组切片返回的是数组数据的视图,而不是数值数据的副本。这一点也是 NumPy 数组切片和 Python 列表切片的不同之处:在 Python 列表中,切片是值的副本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
print(x2)

>>> [[12 5 2 4]
[ 7 6 8 8]
[ 1 6 7 7]]

# 从中抽取一个 2×2 的子数组
x2_sub = x2[:2, :2]
print(x2_sub)

>>>[[12 5]
[ 7 6]]

# 现在如果修改这个子数组,将会看到原始数组也被修改了

x2_sub[0, 0] = 99
print(x2_sub)

>>> [[99 5]
[ 7 6]]

print(x2)

>>> [[99 5 2 4]
[ 7 6 8 8]
[ 1 6 7 7]]

创建数组的副本

copy()函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
x2_sub_copy = x2[:2, :2].copy()
print(x2_sub_copy)

>>> [[99 5]
[ 7 6]]

# 如果修改这个子数组,原始的数组不会被改变

x2_sub_copy[0, 0] = 42
print(x2_sub_copy)

>>> [[42 5]
[ 7 6]]

print(x2)

>>>[[99 5 2 4]
[ 7 6 8 8]
[ 1 6 7 7]]